package com.superb.common.database.interceptor;

import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.superb.common.database.handler.SuperbParamsEncryptHandler;
import com.superb.common.utils.StringUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMap;
import org.apache.ibatis.plugin.*;

import java.util.Properties;

/**
 * 用于处理请求数据字段加密
 * 更新/插入
 * @Author: ajie
 * @CreateTime: 2024-05-11 17:46
 */
@Slf4j
@Intercepts({
        @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }),
})
@AllArgsConstructor
public class SuperbEncryptInterceptor implements Interceptor {

    /**
     * 加密秘钥
     */
    private final String fieldEncryKey;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();
        // mapper中的参数
        Object parameter = args[1];
        // 没有参数则不需要加密 eg：update table_xx set=xx where a
        if (StringUtils.isEmpty(parameter)) {
            return invocation.proceed();
        }
        // 如果是多个参数或使用Param注解（Param注解会将参数放置在ParamMap中）
        if (parameter instanceof MapperMethod.ParamMap<?> paramMap) {
            if (paramMap.containsKey(Constants.ENTITY)) {
                Object updateParameter = paramMap.get(Constants.ENTITY);
                if (StringUtils.isNotEmpty(updateParameter)) {
                    if (SuperbParamsEncryptHandler.isEncryptDecrypt(updateParameter)) {
                        SuperbParamsEncryptHandler.encryptEntity(updateParameter, fieldEncryKey);
                    }
                }
            } else if (paramMap.containsKey(Constants.LIST)) {
                Object updateParameter = paramMap.get(Constants.LIST);
                if (StringUtils.isNotEmpty(updateParameter)) {
                    if (SuperbParamsEncryptHandler.isEncryptDecrypt(updateParameter)) {
                        SuperbParamsEncryptHandler.encryptHandler(updateParameter, fieldEncryKey);
                    }
                }
            }
        } else if (SuperbParamsEncryptHandler.isEncryptDecrypt(parameter)) {
            SuperbParamsEncryptHandler.encryptEntity(parameter, fieldEncryKey);
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }

}
